﻿// 引入System命名空间，提供基本的系统类型和异常处理功能
using Multi_protocol_upper_computer.Services;
using System;
// 引入全球化命名空间，提供文化和地区相关的格式化功能
using System.Globalization;
// 引入WPF核心命名空间，提供窗口、控件等基础WPF功能
using System.Windows;
// 引入WPF数据绑定命名空间，提供数据转换和绑定功能
using System.Windows.Data;
// 引入WPF媒体命名空间，提供颜色、画刷等图形相关功能
using System.Windows.Media;
// 引入WPF调度器命名空间，提供UI线程定时器功能
using System.Windows.Threading;

// 定义项目的根命名空间
namespace Multi_protocol_upper_computer
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑类
    /// 继承自Window类，是WPF应用程序的主窗口
    /// 负责处理主界面的用户交互、导航控制和界面状态管理
    /// 提供系统时间显示、标签页切换、应用程序信息展示等功能
    /// 作为应用程序的入口界面，协调各个功能模块的切换
    /// </summary>
    public partial class MainWindow : Window
    {
        // 定义UI线程定时器私有字段，用于定期更新界面显示的时间
        // DispatcherTimer确保定时器事件在UI线程中执行，避免跨线程操作问题
        private DispatcherTimer _timer;

        /// <summary>
        /// 主窗口构造函数
        /// 初始化窗口组件和相关功能
        /// 在窗口显示前完成所有必要的设置
        /// </summary>
        public MainWindow()
        {
            // 调用InitializeComponent方法初始化XAML中定义的UI组件
            // 这个方法由WPF自动生成，负责创建窗口中的所有控件
            // 必须在访问任何XAML定义的控件之前调用
            InitializeComponent();
            
            // 调用自定义方法初始化时间显示定时器
            // 启动定时器用于实时更新界面上的时间显示
            InitializeTimer();
            
            // 初始化子视图
            InitializeViews();
        }

        /// <summary>
        /// 初始化计时器方法
        /// 创建并配置用于更新界面时间显示的定时器
        /// 设置定时器间隔和事件处理程序
        /// </summary>
        private void InitializeTimer()
        {
            // 创建新的DispatcherTimer实例
            // DispatcherTimer是WPF专用的定时器，在UI线程中执行，线程安全
            _timer = new DispatcherTimer();
            
            // 设置定时器触发间隔为1秒
            // TimeSpan.FromSeconds(1)创建1秒的时间间隔
            // 每秒触发一次用于更新时间显示
            _timer.Interval = TimeSpan.FromSeconds(1);
            
            // 订阅定时器的Tick事件，指定事件处理方法
            // 当定时器间隔到达时会自动调用Timer_Tick方法
            _timer.Tick += Timer_Tick;
            
            // 启动定时器，开始定期触发Tick事件
            // 调用Start()后定时器开始工作，按设定间隔触发事件
            _timer.Start();
        }

        /// <summary>
        /// 计时器事件处理方法
        /// 每秒自动调用一次，用于更新界面上的时间显示
        /// 将当前系统时间格式化后显示在TimeText控件中
        /// </summary>
        /// <param name="sender">事件发送者，这里是_timer对象</param>
        /// <param name="e">事件参数，包含事件相关信息</param>
        private void Timer_Tick(object sender, EventArgs e)
        {
            // 获取当前系统时间并格式化为字符串，然后赋值给TimeText控件的Text属性
            // DateTime.Now：获取当前系统日期和时间
            // ToString("yyyy-MM-dd HH:mm:ss")：格式化为"年-月-日 时:分:秒"格式
            // TimeText：XAML中定义的文本控件，用于显示时间
            TimeText.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        }

        /// <summary>
        /// 数据采集按钮点击事件处理方法
        /// 当用户点击数据采集导航按钮时调用
        /// 切换到数据采集功能界面并更新状态显示
        /// </summary>
        /// <param name="sender">事件发送者，即被点击的按钮控件</param>
        /// <param name="e">路由事件参数，包含事件传播信息</param>
        private void DataCollection_Click(object sender, RoutedEventArgs e)
        {
            // 调用ShowTab方法切换到数据采集标签页
            // DataCollectionTab：XAML中定义的数据采集标签页控件
            ShowTab(DataCollectionTab);
            
            // 更新状态栏文本，显示当前界面信息
            // StatusText：XAML中定义的状态文本控件
            StatusText.Text = "数据采集界面";
        }

        /// <summary>
        /// 通信配置按钮点击事件处理方法
        /// 当用户点击通信配置导航按钮时调用
        /// 切换到通信配置功能界面并更新状态显示
        /// </summary>
        /// <param name="sender">事件发送者，即被点击的按钮控件</param>
        /// <param name="e">路由事件参数，包含事件传播信息</param>
        private void Communication_Click(object sender, RoutedEventArgs e)
        {
            // 调用ShowTab方法切换到通信配置标签页
            // CommunicationTab：XAML中定义的通信配置标签页控件
            ShowTab(CommunicationTab);
            
            // 更新状态栏文本，显示当前界面信息
            StatusText.Text = "通信配置界面";
        }

        /// <summary>
        /// 日志查看按钮点击事件处理方法
        /// 当用户点击日志查看导航按钮时调用
        /// 切换到日志查看功能界面并更新状态显示
        /// </summary>
        /// <param name="sender">事件发送者，即被点击的按钮控件</param>
        /// <param name="e">路由事件参数，包含事件传播信息</param>
        private void Log_Click(object sender, RoutedEventArgs e)
        {
            // 调用ShowTab方法切换到日志查看标签页
            // LogTab：XAML中定义的日志查看标签页控件
            ShowTab(LogTab);
            
            // 更新状态栏文本，显示当前界面信息
            StatusText.Text = "日志查看界面";
        }

        /// <summary>
        /// 关于按钮点击事件处理方法
        /// 当用户点击关于按钮时调用
        /// 显示应用程序的版本信息、功能特性和开发环境信息
        /// </summary>
        /// <param name="sender">事件发送者，即被点击的按钮控件</param>
        /// <param name="e">路由事件参数，包含事件传播信息</param>
        private void About_Click(object sender, RoutedEventArgs e)
        {
            // 使用MessageBox显示应用程序信息对话框
            MessageBox.Show(
                // 对话框内容文本，包含应用程序名称、版本和功能列表
                "多协议上位机系统 v1.0\n\n" +           // 应用程序标题和版本号
                "支持功能:\n" +                        // 功能列表标题
                "• Modbus TCP/RTU 通信\n" +           // 支持Modbus协议通信
                "• 串口通信\n" +                      // 支持串口通信
                "• TCP/UDP 通信\n" +                  // 支持网络通信协议
                "• 数据采集与存储\n" +                // 支持实时数据采集和数据库存储
                "• 实时日志监控\n" +                  // 支持日志记录和监控功能
                "• 数据加密传输\n\n" +                // 支持数据加密安全传输
                "开发框架: .NET Framework 4.8.1",    // 显示开发技术栈信息
                "关于",                               // 对话框标题
                MessageBoxButton.OK,                 // 只显示确定按钮
                MessageBoxImage.Information);        // 显示信息图标
        }

        /// <summary>
        /// 退出按钮点击事件处理方法
        /// 当用户点击退出按钮时调用
        /// 显示确认对话框，确认后安全退出应用程序
        /// </summary>
        /// <param name="sender">事件发送者，即被点击的按钮控件</param>
        /// <param name="e">路由事件参数，包含事件传播信息</param>
        private void Exit_Click(object sender, RoutedEventArgs e)
        {
            // 显示确认退出对话框，获取用户选择结果
            var result = MessageBox.Show(
                "确定要退出应用程序吗？",              // 确认询问文本
                "确认退出",                          // 对话框标题
                MessageBoxButton.YesNo,             // 显示是/否两个按钮
                MessageBoxImage.Question);          // 显示问号图标

            // 检查用户是否选择了"是"按钮
            if (result == MessageBoxResult.Yes)
            {
                // 调用Application.Current.Shutdown()方法正常关闭应用程序
                // 这会触发应用程序的关闭流程，包括资源清理和事件处理
                Application.Current.Shutdown();
            }
            // 如果用户选择"否"，方法结束，应用程序继续运行
        }

        /// <summary>
        /// 初始化子视图方法
        /// 创建并加载各个功能模块的用户控件
        /// </summary>
        private void InitializeViews()
        {
            try
            {
                // 创建数据采集视图
                var dataCollectionView = new Views.DataCollectionView();
                DataCollectionContent.Children.Clear();
                DataCollectionContent.Children.Add(dataCollectionView);

                // 创建通信配置视图 - 修复：通信配置标签页没有内容容器
                var communicationViewModel = new ViewModels.CommunicationViewModel(); // 新增：创建ViewModel实例
                var communicationView = new Views.CommunicationView(communicationViewModel); // 传递viewModel参数
                // CommunicationTab是TabItem，需要创建内容容器
                if (CommunicationTab.Content == null)// 确保CommunicationTab有内容容器
                {
                    CommunicationTab.Content = new System.Windows.Controls.Grid();
                }
                // 获取CommunicationTab的内容容器并添加通信视图
                var communicationContent = CommunicationTab.Content as System.Windows.Controls.Panel;
                // 清空现有内容并添加新的通信视图
                communicationContent?.Children.Clear();
                // 添加通信视图到内容容器
                communicationContent?.Children.Add(communicationView);

                // 创建日志查看视图 - 修复：日志标签页没有内容容器
                var loggingService = new LoggingService(); // 你需要有ILoggingService的实现
                var dataService = new DataService();       // 你需要有IDataService的实现
                var logViewModel = new ViewModels.LogViewModel(loggingService, dataService); // 传递所需参数
                var logView = new Views.LogView(logViewModel); // 传递viewModel参数
                    // LogTab是TabItem，需要创建内容容器
                    if (LogTab.Content == null)
                    {
                        LogTab.Content = new System.Windows.Controls.Grid();
                    }
                    var logContent = LogTab.Content as System.Windows.Controls.Panel;
                    logContent?.Children.Clear();
                    logContent?.Children.Add(logView);
                    
                // 调试信息
                System.Diagnostics.Debug.WriteLine("所有视图初始化完成");
            }
            catch (Exception ex)
            {
                // 如果视图初始化失败，显示错误信息
                System.Diagnostics.Debug.WriteLine($"视图初始化失败: {ex.Message}");
                System.Diagnostics.Debug.WriteLine($"异常详情: {ex}");
                MessageBox.Show($"初始化视图失败: {ex.Message}\n\n详细信息:\n{ex}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 显示指定标签页的方法
        /// 实现标签页的显示和隐藏控制，确保同时只显示一个标签页
        /// 采用手动控制可见性的方式而非标准TabControl行为
        /// </summary>
        /// <param name="tab">要显示的标签页控件</param>
        private void ShowTab(System.Windows.Controls.TabItem tab)
        {
            // 首先隐藏所有标签页，确保界面的独占显示
            // 将每个标签页的Visibility属性设置为Collapsed（折叠/隐藏）
            
            // 隐藏主页标签页
            HomeTab.Visibility = Visibility.Collapsed;
            // 隐藏数据采集标签页
            DataCollectionTab.Visibility = Visibility.Collapsed;
            // 隐藏通信配置标签页
            CommunicationTab.Visibility = Visibility.Collapsed;
            // 隐藏日志查看标签页
            LogTab.Visibility = Visibility.Collapsed;

            // 显示指定的标签页
            // 将目标标签页的Visibility属性设置为Visible（可见）
            tab.Visibility = Visibility.Visible;
            
            // 设置TabControl的选中项为当前显示的标签页
            // 这确保了TabControl的内部状态与实际显示状态保持一致
            MainTabControl.SelectedItem = tab;
        }

        /// <summary>
        /// 窗口关闭事件重写方法
        /// 当窗口即将关闭时自动调用
        /// 执行必要的资源清理工作，确保应用程序正常退出
        /// </summary>
        /// <param name="e">事件参数，包含关闭相关信息</param>
        protected override void OnClosed(EventArgs e)
        {
            // 安全地停止定时器，避免内存泄漏
            // 使用?.操作符确保即使_timer为null也不会抛出异常
            // Stop()方法停止定时器的触发，释放相关资源
            _timer?.Stop();
            
            // 调用基类的OnClosed方法，确保正常的关闭流程
            // 这会触发其他必要的清理操作和事件处理
            base.OnClosed(e);
        }
    }


}
